Repository navigation
Release: merge development into beta - #1210
github-actions[bot] wants to merge 200 commits into
Conversation
…0261007125751 chore(sync): carry beta back into development
…1) (#1181) * test(mobile): offline reading and accessibility audits on Android and iOS (tasks 3.4, 3.1) OfflineReadingTest syncs, cuts the network and proves the server is out of reach, unlocks offline, reads an item from the store with the last-synced note, finds every edit refused, and syncs again once the network is back. AccessibilityAuditTest runs the Accessibility Test Framework through Compose's enableAccessibilityChecks on the main screens (API 34); AccessibilityAuditUITests runs performAccessibilityAudit on the same screens on iOS. Both collect every finding and fail once at the end with the list. * build(mobile): name every shared-core test in the CI log The Mobile jobs showed only the Gradle tasks. Ticking a task against CI needs the test that ran, so the jvm, Android and iOS simulator tests now log each test with its result. * test(mobile): the offline test reads the store file without its key (task 1.6) After the sync, the SQLCipher file and its journal hold no SQLite header and none of the demo vault's names, logins or addresses, and plain SQLite refuses to read it. * docs(parity): clients-10 is building, with the merged mobile PRs and the preview release parity_verify --strict: no finding but the unknown-cells census. * build(mobile): checksums for the jars the Android test classpath selects guava 31.0.1-android, checker-qual 3.22.1 and j2objc-annotations 1.3 win on the androidTest classpath (the existing guava entries are the jre variant). Their sha256 was checked against Maven Central's published sha1. The other binaries of the accessibility test closure are listed too, so a version that wins resolution is never missing. * fix(mobile): the accessibility audit's findings on Android and iOS (task 3.1) Android: the auto-lock radio rows were 24 dp touch targets; they are 48 dp. iOS: Keepiq's own tint and secondary text colour pass WCAG AA (the system blue is 4.0:1 on white), section headers use it, the generator's refresh button takes taps on 44 pt, a Send row is one element, the code countdown grows with Dynamic Type, and a long value wraps instead of clipping. Three audit kinds are excluded with their reason in A11yExclusions: clipping on single-line text fields, the item's own login or address as a label, and SwiftUI text styles reported as partially unsupported. * fix(mobile): the remaining iOS audit findings (task 3.1) A darker red for destructive list buttons (the system red is 3.6:1 on white), the code countdown in Keepiq's tint with primary text, a field row that puts its buttons under a long value at the accessibility text sizes, and a generated value that wraps. The audit no longer counts contrast on a disabled control (WCAG 1.4.3 exempts inactive components) or on text that iOS 26 fades under a bar on purpose (the scroll edge effect). * fix(mobile): last iOS audit findings: explicit tint on Edit and Move, plain countdown label, no disabled Send password field The one-time code gets its own list section, so its refresh does not re-lay out the address. The audit leaves out a contrast finding it cannot tie to an element only while a list row sits under a bar. * test(mobile): measure contrast from the screenshot before counting an iOS audit finding The audit flags the Edit button although its pixels are Keepiq's tint on white (7.1:1), the same as the Move button that passes. A contrast finding is now left out only when the measured ratio is 4.5:1 or more. The audit also holds the one-time code still, since a countdown redrawing during the pass made it report the address as clipped. * fix(mobile): let a long address wrap at its slashes and dots on iOS A value without spaces could only be cut off at large text sizes; the audit reported the address on the one-time code screen as clipped. A zero-width space after each slash, dot and @ gives it break points, while VoiceOver and Copy keep the value as it is. Drops the held countdown, which did not change the finding. * docs(openspec): tick the clients-mobile-apps tasks CI now covers, split out the manual device checks
Quality Report — ConductionNL/keepiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-l10n-js | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| composer | ✅ | ✅ 114/114 | |||
| npm | ✅ | ✅ 660/660 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ✅ | ||||
| lockfile sync | ✅ | ||||
| PHPUnit | ⏭️ not run for this diff — no file in this diff matches the code globs, and none carries a source extension — the heavy tier has nothing to decide about it. | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ not run for this diff — no file in this diff matches the code globs, and none carries a source extension — the heavy tier has nothing to decide about it. | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-10-07 15:01 UTC
Download the full PDF report from the workflow artifacts.
…ived changes Step 1: clients-15 gets openspec/changes/clients-vault-event-flow-triggers. Step 2: twelve unbuilt rows pointed at changes that were archived on 2026-10-04; their links now name the archive path.
…delivered it Step 3: 132 built rows had no link. 59 now name the archived change that delivered them, 71 name the main spec (several changes shaped it), and two (clients-16 theming, clients-17 walkthrough) were never specified.
…none Step 4: extension generator, extension sends, extension vault, extension offline snapshot and the metadata-only AI assistant tools were specified and built but had no capability row. Competitor cells are unknown.
Step 5: 152 rows name their board(s) on canvas 5NkFW28vZUUij43xzxHg5a; 48 rows have no board, with the reason (backend, a Nextcloud or integriq surface, or not designed yet).
…links docs(openspec): specs for unbuilt capabilities, capability-to-spec links
…4 October Ten rows are built on development and read built; apps-22 (registry publication owed) and clients-01 (store listings owed) read building. audit-15 stays partial with sharper evidence: no alert for failed unlocks or admin changes.
clients-17 was built without a spec. The new main spec describes the manifest tour, the lock-state gate and the per-user completion preference as they are on development. clients-16 stays spec none: theming comes from Nextcloud theming or thematiq.
docs(openspec): re-rated rows and specs for unspecified built capabilities
Quality Report — ConductionNL/keepiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-l10n-js | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| composer | ✅ | ✅ 114/114 | |||
| npm | ✅ | ✅ 660/660 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ✅ | ||||
| lockfile sync | ✅ | ||||
| PHPUnit | ⏭️ not run for this diff — no file in this diff matches the code globs, and none carries a source extension — the heavy tier has nothing to decide about it. | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ not run for this diff — no file in this diff matches the code globs, and none carries a source extension — the heavy tier has nothing to decide about it. | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-10-07 21:25 UTC
Download the full PDF report from the workflow artifacts.
Archives client-side-key-generator and standalone-app-shell; the latter removes every apphost-adoption requirement, so that capability is retired.
docs(openspec): archive pass, changes the code has delivered
Quality Report — ConductionNL/keepiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-l10n-js | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| composer | ✅ | ✅ 114/114 | |||
| npm | ✅ | ✅ 660/660 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ✅ | ||||
| lockfile sync | ✅ | ||||
| PHPUnit | ⏭️ not run for this diff — no file in this diff matches the code globs, and none carries a source extension — the heavy tier has nothing to decide about it. | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ not run for this diff — no file in this diff matches the code globs, and none carries a source extension — the heavy tier has nothing to decide about it. | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-10-07 22:52 UTC
Download the full PDF report from the workflow artifacts.
…new boards Every row with a Keepiq board now points at canvas part 2 (QAAxpcsFKBCvDUGbQbwtCa); clients-15 keeps part 1 for pipelinq's flow boards. Five of the six new boards are mapped (KqRondleiding gives clients-17 its first board); KqMeldingen is a catalogue of empty states with no capability of its own.
docs(openspec): link capabilities to the split design canvas and its new boards
Quality Report — ConductionNL/keepiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-l10n-js | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| composer | ✅ | ✅ 114/114 | |||
| npm | ✅ | ✅ 660/660 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ✅ | ||||
| lockfile sync | ✅ | ||||
| PHPUnit | ⏭️ not run for this diff — no file in this diff matches the code globs, and none carries a source extension — the heavy tier has nothing to decide about it. | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ not run for this diff — no file in this diff matches the code globs, and none carries a source extension — the heavy tier has nothing to decide about it. | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-10-08 05:56 UTC
Download the full PDF report from the workflow artifacts.
Delete the old extension's tests, workflows (browser-extension, extension-release, docs-media) and user docs. Move the test Nextcloud harness that mobile-e2e and standalone use from browser-extension/capture to tests/server. Freeze the autofill and passkey vectors that the old extension wrote.
WXT 0.21 made web-ext an optional peer dependency. Without it, wxt dev silently falls back to its manual runner and never launches a browser.
…nd opens One page per fill and capture case in the ext-autofill specs: iframes, shadow DOM, multi-step, honeypot fields, framework-controlled inputs, sign-up, change password and more, so nobody needs a real Nextcloud page to try the extension. The dev browser keeps a persistent profile in .wxt/chrome-data.
Read it from xdg-settings on Linux and the registry on Windows, and use it for the target it fits. Elsewhere WXT's own detection applies, and a local web-ext.config.ts still overrides it.
…tabs Let web-ext manage the persistent profile through chromiumProfile, so its chromiumPref reaches the profile Brave opens, and set it to start on a new tab. Also hide the crash restore prompt that stopping dev would trigger.
Grey when logged out, a lock when locked, and a count of the logins matching the tab when unlocked, as in Bitwarden.
Render public/icon from img/app-store.svg instead of the placeholder art, and base the toolbar icon variants in the ext-toolbar-icon spec on it.
…d-unlock) Add the Keepiq API client, the crypto module (byte compatible with the web app, tested against its vectors), the account store, the key store, the timeout engine and the background message router, with a React popup for adding accounts, unlocking, logging in again and switching accounts. Every module and popup component has vitest tests. The popup treats a reply that is not a Result as an error instead of rendering nothing, and npm run dev clears the dev profile's service workers so Chromium runs the current background.js instead of a stale registered one.
Support Nextcloud under a subpath by storing a server URL instead of an origin, and drop .local from the plain http allow list. A wrong master password on a cached suite fetches the suites once, so a password changed in the web app unlocks. The background replies through sendResponse, which every Chrome accepts, now that WXT ships no polyfill. Log out asks for confirmation everywhere and the switcher buttons name their account. The Add account draft lives in storage.session so it survives the popup closing, and focus returns to the field to fix. The "Never" key follows the timeout policy and settings changes, the certificate parser and RSA decrypt reject malformed lengths, a 5xx reads as the server being unavailable, and a CI workflow runs the extension's tests, typecheck, lint and both builds.
Fix GHSA-6ghh-m46w-7fmw: encrypt federated shares to the verified certificate key
| }) | ||
|
|
||
| it('refuses characters outside the base64 alphabet', () => { | ||
| expect(refusal(pem(BOB_DER).replace('\n', '\n*'))).toMatch(NOT_ONE_BLOCK) |
…hare-save # Conflicts: # src/store/modules/federatedShare.js # tests/store/federatedShare.sync.spec.js
Quality Report — ConductionNL/keepiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ❌ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-l10n-js | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| composer | ❌ | ✅ 114/114 | |||
| npm | ✅ | ✅ 660/660 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ✅ | ||||
| lockfile sync | ✅ | ||||
| PHPUnit | ✅ 2141/2141 · 3 skipped (8 legs, 2022–2141 tests per leg) | ||||
| Newman | ✅ 177/177 · 20 skipped | ||||
| Playwright | ✅ 99/99 · 6 skipped | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-10-15 13:11 UTC
Download the full PDF report from the workflow artifacts.
feat(sharing): save a shared secret and every copy in one request
Quality Report — ConductionNL/keepiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-l10n-js | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| composer | ✅ | ✅ 114/114 | |||
| npm | ✅ | ✅ 660/660 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ✅ | ||||
| lockfile sync | ✅ | ||||
| PHPUnit | ✅ 2321/2321 · 3 skipped (8 legs, 2191–2321 tests per leg) | ||||
| Newman | ✅ 177/177 · 20 skipped | ||||
| Playwright | ✅ 106/106 · 7 skipped | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-10-15 14:31 UTC
Download the full PDF report from the workflow artifacts.
Bumps [phpstan/phpstan](https://github.com/phpstan/phpstan-phar-composer-source) from 2.2.16 to 2.3.1. - [Commits](https://github.com/phpstan/phpstan-phar-composer-source/commits) --- updated-dependencies: - dependency-name: phpstan/phpstan dependency-version: 2.3.1 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [phpseclib/phpseclib](https://github.com/phpseclib/phpseclib) from 4.0.1 to 4.0.2. - [Release notes](https://github.com/phpseclib/phpseclib/releases) - [Changelog](https://github.com/phpseclib/phpseclib/blob/master/CHANGELOG.md) - [Commits](phpseclib/phpseclib@4.0.1...4.0.2) --- updated-dependencies: - dependency-name: phpseclib/phpseclib dependency-version: 4.0.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
The background gives a use-only copy's holder its login and refuses its key and additional fields with `use_only`, so the rule holds whatever the popup asks. The popup offers only the username to copy and shows a use-only item's login, site and a note instead of its value.
Quality Report — ConductionNL/keepiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-l10n-js | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| composer | ✅ | ✅ 114/114 | |||
| npm | ✅ | ✅ 660/660 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ✅ | ||||
| lockfile sync | ✅ | ||||
| PHPUnit | ✅ 2321/2321 · 3 skipped (8 legs, 2191–2321 tests per leg) | ||||
| Newman | ✅ 177/177 · 20 skipped | ||||
| Playwright | ✅ 106/106 · 7 skipped | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-10-16 07:54 UTC
Download the full PDF report from the workflow artifacts.
A copy with no stored delay, or an invalid one, now clears after 30 s; a stored 0 means never. Every copy also cancels a clear still pending from an earlier copy, so that clear can't wipe a newer copy made with Never.
The old extension is deleted, and its files were still cited as proof that fill, save prompts, passkeys, biometric unlock, use-only fill, the generator and sends were built. Rows the new extension doesn't deliver now read no and specified, pointing at the ext-* change or root spec that describes them. Rows it does deliver (accounts, lock, account linking, browsing, the offline snapshot, the Chrome and Firefox builds) cite its files instead. Rows where the old extension only supplied part of the evidence keep their web app evidence; crypto-09 and sharing-24 drop to partial.
feat: Add the new Keepiq browser extension (accounts, unlock, vault browsing)
Quality Report — ConductionNL/keepiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-l10n-js | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| composer | ✅ | ✅ 114/114 | |||
| npm | ✅ | ✅ 660/660 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ✅ | ||||
| lockfile sync | ✅ | ||||
| PHPUnit | ✅ 2321/2321 · 3 skipped (8 legs, 2191–2321 tests per leg) | ||||
| Newman | ✅ 177/177 · 20 skipped | ||||
| Playwright | ✅ 105/105 · 7 skipped | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-10-16 09:36 UTC
Download the full PDF report from the workflow artifacts.
… refuse an answer for another account The web app refuses a certificate lookup answer whose cloud id isn't the one asked for, after the server's own normalisation. The share form refuses it; a share-save suspends that partner share as one whose certificate no longer verifies, so the save and the offline queue go on. The verifier refuses what the browser extension's port refuses: a self-issued intermediate, an empty cloud id on either side, an outer signature algorithm that differs from the TBS one, a signature with unused bits, strict common-name rules on the leaf only, and strict RSA-PSS parameters. It also refuses a leaf marked cA=TRUE, without backwards compatibility, and folds only the host's case of a cloud id. PARTNER_GONE pairs each reason with its status, so a reason on another status, such as a proxy's 500, is an ordinary error and suspends nothing. The browser root pin is dropped: the web app trusts its own server, which the spec records as a known limit. Closes #1257
…ches them Review thread: #1288 (comment) certificate() takes a tbsTag option (default 0x30). Each new leaf is signed over exactly the bytes it carries, so only the guard refuses it: - tbs?.tag !== 0x30 (parse) -> "refuses a leaf whose TBS is no SEQUENCE, though it is signed as such" - algorithm?.tag !== 0x30 (parse) -> "refuses a signature algorithm that is no SEQUENCE, though the same inside and outside the TBS" - if (extra) in algorithmOf -> "refuses a signature algorithm with a third part, though the same inside and outside the TBS" - saltLength = derUint(bytes, inner) -> "refuses a PSS salt length that is negative as malformed" (the base's byte loop reads 128 and gives bad_chain) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fix(review): #1288 review findings, round 1
…icate parser Every caller of children passes an element that is already checked, and a TypeError there would end as malformed in verifyFederatedCertificate's catch, so no input could reach it. Review finding f1 on #1288.
fix(federation): check a partner recipient's certificate strictly and refuse an answer for another account
Quality Report — ConductionNL/keepiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-l10n-js | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| composer | ✅ | ✅ 114/114 | |||
| npm | ✅ | ✅ 660/660 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ✅ | ||||
| lockfile sync | ✅ | ||||
| PHPUnit | ✅ 2321/2321 · 3 skipped (8 legs, 2191–2321 tests per leg) | ||||
| Newman | ✅ 177/177 · 20 skipped | ||||
| Playwright | ✅ 105/105 · 7 skipped | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-10-19 13:18 UTC
Download the full PDF report from the workflow artifacts.
Automated PR to sync development changes to beta for beta release.
Merging this PR will trigger the beta release workflow.